home *** CD-ROM | disk | FTP | other *** search
Text File | 1994-07-22 | 10.2 KB | 264 lines | [TEXT/KAHL] |
- // Reorder Views Plugin
- // ©by Ben Weiss, 6/21/94
- // Show a menu item called 'Reorder Views' in the Views menu. When selected, sort
- // the current topic's views alphabetically.
-
- // Revision 1.1 6/22/94 Added code to count views in ATM & changed resource ids to -512
- // Revision 1.2 7/22/94 support Undo; messed with resource ID's
-
- // To see all the arNoteID's & such,
- // go into the debug window & type i<noteid> & hit enter
- // (1000 decimal is id of root folder)
-
- #include "ArrangeCallbacks.h"
- #include "PluginLibrary.h"
-
- #include <Dialogs.h> // for my about box
-
- // Remember that your moduleResourceID should be a negative multiple of 0x200 and must
- // be registered with Common Knowledge, Inc. Also, your ModuleID must be unique and
- // also registered with Common Knowledge, Inc.
- #define moduleID 0x10000006 // my module ID is 0x10000006 "Reorder Views"
- #define moduleResID 0xFFFF8000 // was -512 in v.1.1
- #define reorderViewCode 'bw a'
- #define aboutCode 'bw '
-
-
-
- class ReorderViews
- {
- public:
- ReorderViews(const ArrangeCallbackTbl* theCalls);
- ~ReorderViews();
-
- arHookResult MenuNotify (Integer menuCode, Integer menuParam, pShort modifiers);
- void AboutToMenu();
-
- private:
- const ArrangeCallbackTbl* calls; // callback table
-
- void DoIt();
- }; // ReorderViews
-
-
- /*************************************************************************/
- /**************************** Main entry point ***************************/
- /*************************************************************************/
-
- /* Root entry point for the module - must be the first function in the
- * file, so that the linker will place it first in the code segment.
- */
- extern "C" Integer main (ModuleParamBlock *pb, ModuleRootAction action, Integer)
- {
- ArrangeCallbackTbl* calls = (ArrangeCallbackTbl*)(pb->calls);
-
- switch (action)
- {
- case mrLoad:
- {
- // Allocate memory and create a new OurPlugin object.
- void* storage = calls->mem->AllocMem( sizeof(ReorderViews), amFreeStore | amErrIfNoMem );
- pb->moduleRefcon = uInteger(new(storage) ReorderViews(calls));
- return 1;
- }
-
- case mrUnload:
- {
- // Dispose of the ReorderViews object
- delete (ReorderViews*)(pb->moduleRefcon);
- calls->mem->DeallocMem((void*)(pb->moduleRefcon), amFreeStore);
- return 0;
- }
- default:
- return 0;
-
- } // switch (action)
-
- } // main
-
- static arHookResult OurMenuHook (ModuleParamBlock* pb, Integer menuCode, Integer menuParam, pShort modifiers ENDP)
- {
- return ((ReorderViews*)(pb->moduleRefcon))->MenuNotify (menuCode, menuParam, modifiers );
- } // OurMenuHook
-
-
- void OurATMHook(ModuleParamBlock* pb ENDP)
- {
- ((ReorderViews*)(pb->moduleRefcon))->AboutToMenu();
- } // OurATMHook
-
-
- //*************************************************************************
- //******************************* Entry Point *****************************
- //*************************************************************************
-
- // Make an object. This is called once, from the ModuleRoot function,
- // when the module is initialized (i.e. at application boot time).
-
- ReorderViews::ReorderViews (const ArrangeCallbackTbl* theCalls)
- {
- calls = theCalls;
-
- //Add an item with the given name, command key (0 if none), command-code, and refcon
- //to the end of the menu with the given code. By default the item will be enabled and unchecked.
- //If itemName is "-", then the item will be disabled and will be drawn as a gray bar.
- //No other Menu Manager metacharacters are supported.
-
- calls->ui->AddMenuItem (mTopics, "-", 0, 0, 0); // a gray line
- calls->ui->AddMenuItem (mTopics, "Reorder Views", 0, reorderViewCode, 0);
- calls->ui->AddMenuItem (mPluginAbout, "About Reorder Views", 0, aboutCode, 0);
-
- // Add or remove a hook from the menu item(s) with the given code.
- // If the code is nil, the hook will be notified whenever any menu item is chosen.
- // The hook function should return true if it handled the command, false if it did not.
- // If it returns false, control will pass to the next registered hook function for the menu item,
- // and eventually to the standard application code (if any).
-
- calls->ui->SetMenuHook (OurMenuHook, 0, true, reorderViewCode);
- calls->ui->SetMenuHook (OurMenuHook, 0, true, aboutCode);
- calls->ui->SetATMHook (OurATMHook, 0, true); // ATM = About To Menu
- } // ReorderViews constructor
-
-
- ReorderViews::~ReorderViews() {} //ReorderViews distructor; Dispose of a ReorderViews object.
-
-
- /* This function is called whenever the user chooses a menu item for which
- * we have registered (via the SetMenuHook callback function). It should
- * return true if we handle the menu item ourselves, false to let the
- * application process it.
- */
- arHookResult ReorderViews::MenuNotify (Integer menuCode, Integer menuParam, pShort modifiers)
- {
- if (menuCode == reorderViewCode)
- {
- DoIt();
- return true;
- }
- else if (menuCode == aboutCode)
- {
- Alert (moduleResID, nil);
- return true;
- }
- else
- return false;
-
- } // MenuNotify
-
-
- /* This function is called whenever the user clicks in the menu bar or types
- * a command key, just before processing the event. It does any fixing up
- * of menus which might be necessary based on the current state of affairs.
- * In our case, the only thing we do is disable our menu item if there is no
- * open document window
- */
-
- void ReorderViews::AboutToMenu()
- {
- arWindowID currFrontWin = calls->sel->GetActiveWindow ();
- if (currFrontWin == nil) // no window -- dim the lamps
- // void SetMenuItem( Short menuCode, Integer commandCode, Integer itemRefcon,
- // const char* itemName, Boolean itemEnabled, Short markChar, Short itemStyle );
- // Set the title, enabled state, mark character, and style for the menu item with
- // the given code and refcon. If no such item exists, log an error.
- // If itemName is nil, then the item's title is unchanged.
- calls->ui->SetMenuItem (mTopics, reorderViewCode, 0, nil, false, 0, 0);
- else
- { // Okay-- we have a window. But are there any views?
- pBoolean returnRoot = true; /* will this alawys return a arTopicID? */
- arTopicID thisTopic = calls->sysObj->GetCurrentTopic (currFrontWin, returnRoot);
- arFieldID viewsField = calls->sysObj->GetBuiltInObject (boTopicViewsField);
- if (calls->data->GetFieldListLen (thisTopic, viewsField) < 2)
- calls->ui->SetMenuItem (mTopics, reorderViewCode, 0, nil, false, 0, 0);
- else
- calls->ui->SetMenuItem (mTopics, reorderViewCode, 0, nil, true, 0, 0);
- }
- } // AboutToMenu
-
-
- void ReorderViews::DoIt()
- {
- //----------------------------------------
- // Return the ID of the frontmost window for the current document.
- // If the document has no open windows, return nil.
- // Note that this function will return hoist windows as well as regular document windows.
-
- arWindowID currFrontWin = calls->sel->GetActiveWindow ();
- if (currFrontWin)
- {
- // What do I do if the current window is a hoist window?
-
-
- //----------------------------------------
- // Return the ID of the current (selected) topic or folder in this window.
- // If the window is showing a view, and returnRoot is false,
- // then return the ID of the view itself; otherwise return the ID of its parent topic or folder.
-
- pBoolean returnRoot = true; /* will this alawys return a arTopicID? */
- arTopicID thisTopic = calls->sysObj->GetCurrentTopic (currFrontWin, returnRoot);
-
- //----------------------------------------
- // Get the field ID of the field inside this note which has the view info in it.
-
- arFieldID viewsField = calls->sysObj->GetBuiltInObject (boTopicViewsField);
-
- //----------------------------------------
- // Put the views into a list object
-
- arListID myList;
- myList = calls->data->GetFieldList (thisTopic, viewsField);
-
- //----------------------------------------
- // Return a new list containing the same notes as the input list,
- // but sorted according to the given sorting rule.
- // The first clause has primary importance; subsequent clauses are used to break ties.
- // If two notes tie on all clauses, the retain the same relative order as in the input list.
- // Constants for the type field of an arSortClause record.
-
- arFieldID nameField;
- nameField = calls->sysObj->GetBuiltInObject (boNameField);
-
- arSortClause mySortClause;
- mySortClause.type = sAscending;
- mySortClause.field = nameField;
-
- arListID mySortedList;
- mySortedList = calls->search->SortNotes (myList, 1, &mySortClause);
-
- //----------------------------------------
- /// void SetupUndo(const char* operationName, Boolean setChangedFlag);
- /// Mark the beginning of an undoable operation with the given name.
- /// That name (prefixed with the string “Undo ” or “Redo ”) will appear
- /// in the Edit menu, and choosing it will cause the document to revert
- /// to its state at the present moment. If setChangedFlag is true, the
- /// document will be marked as having unsaved changes (see the SetChangedFlag
- /// function for details). If you pass nil for the name parameter, then Undo
- /// will be disabled (i.e. any existing undo state will be thrown away);
- /// the setChangedFlag parameter is still respected in this case.
- ///
- /// You should generally make this call as late as possible in the execution
- /// of a command, just before you start to actually change the state of the
- /// document. In particular, you should almost always call FlushSelection
- /// before SetupUndo, and not call SetupUndo if FlushSelection returns false.
- calls->doc->SetupUndo ("Reorder Views", true);
-
- //----------------------------------------
- // Now put the newly sorted list into the note link field for views for this topic
- // Overwrite the contents of a note-link field with a list of notes contained
- // in a ListID; if the note doesn’t have this field, add it as an invisible field.
- // If the field isn’t a note-link field, log an error and do nothing.
- //
- // If the sfDisableModDate flag is set, then don't update the note's modification
- // date and last editor name. A nil value for the list parameter is interpreted as
- // the empty list.
- //
- // void SetFieldList( arNoteID note, arFieldID field, arListID list, arSetFieldFlags flags );
-
- calls->data->SetFieldList (thisTopic, viewsField, mySortedList, nullSFF);
- calls->doc->SetChangedFlag();
-
- //----------------------------------------
- calls->list->DisposeList (mySortedList); // Get rid of the no longer needed list
- calls->list->DisposeList (myList);
- }; // if no current front window
- } // ReorderViews::DoIt()